package com.paireach.bw.utils;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Environment;
import android.os.PowerManager;
import android.os.SystemClock;
import android.text.format.DateUtils;
import android.util.Log;

import com.baidu.location.BDLocationListener;
import com.baidu.trace.LBSTraceClient;
import com.baidu.trace.LocationMode;
import com.baidu.trace.OnEntityListener;
import com.baidu.trace.OnGeoFenceListener;
import com.baidu.trace.OnStartTraceListener;
import com.baidu.trace.OnStopTraceListener;
import com.baidu.trace.OnTrackListener;
import com.baidu.trace.Trace;
import com.baidu.trace.TraceLocation;
import com.baidu.trace.model.CreateLocalFenceResult;
import com.blankj.utilcode.utils.FileUtils;
import com.blankj.utilcode.utils.TimeUtils;
import com.paireach.bw.R;
import com.paireach.bw.application.MyApplication;
import com.paireach.bw.bean.MonitorStatusBean;
import com.paireach.bw.bean.MonitoredPersonStatusesBean;
import com.paireach.bw.bean.TraceAlarmInfo;
import com.paireach.bw.broadcastreceiver.TrackReceiver;
import com.paireach.bw.common.Constant;
import com.paireach.bw.event.AppEvent;
import com.paireach.bw.interface2.LocateCallback;

import org.greenrobot.eventbus.EventBus;

import java.io.File;


/**
 * Created by ${cqc} on 2017/2/4.
 * 1min采集一次，5min上传一次。
 */

public class BDTraceUtil {
    private static final String TAG = "BDTraceUtil";
    public static long serviceId = 133374;// 轨迹服务ID
    public static int traceType = 2;//轨迹服务类型，traceType必须设置为UPLOAD_LOCATION才能追踪轨迹
    private static int gatherInterval = 60;// 采集周期  定位的周期
    private static int packInterval = 300;// 打包周期 上传信息的周期
    private static int protocolType = 1;// http协议类型
    public static LBSTraceClient client;
    public static Trace trace;
    private static String entityName;

    //cpu保活
    private static boolean isRegister = false;
    protected static PowerManager pm = null;
    public static PowerManager.WakeLock wakeLock = null;
    public static TrackReceiver trackReceiver = new TrackReceiver();


    public static void openTrace() {
//        createLogFile();
        //发些在输入姓名有的输入了空格，空格是鹰眼的非法字符，所以用trim()去掉了空格
//        entityName = MyApplication.getSpUtils().getString(Constant.REAL_NAME) + "_" + MyApplication.getSpUtils().getString(Constant.TEL);
        entityName = MyApplication.getSpUtils().getString(Constant.REAL_NAME).trim() + "_" + MyApplication.getSpUtils().getString(Constant.TEL).trim();
        client = new LBSTraceClient(MyApplication.getContext()); //实例化轨迹服务客户端
        trace = new Trace(MyApplication.getContext(), serviceId, entityName, traceType); //实例化轨迹服务
        client.setInterval(gatherInterval, packInterval); // 设置采集和打包周期
        client.setLocationMode(LocationMode.High_Accuracy); // 设置定位模式
        client.setProtocolType(protocolType); // 设置http协议类型


        client.startTrace(trace, startTraceListener); //开启轨迹服务


        //cpu保活
        if (!isRegister) {
            if (null == pm) {
                pm = (PowerManager) MyApplication.getContext().getSystemService(Context.POWER_SERVICE);
            }
            if (null == wakeLock) {
                wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "track upload");
            }
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_SCREEN_ON);
            filter.addAction("com.baidu.trace.action.GPS_STATUS");
            MyApplication.getContext().registerReceiver(trackReceiver, filter);
            isRegister = true;
        }
    }

    //实例化开启轨迹服务回调接口
    public static OnStartTraceListener startTraceListener = new OnStartTraceListener() {


        //开启轨迹服务回调接口（errorNo : 消息编码，message : 消息内容，详情查看类参考）
        @Override
        public void onTraceCallback(int errorNo, String message) {
            LogUtil.d(TAG, "start---onTraceCallback--errorNo=" + errorNo + "---message=" + message);
        }

        //轨迹服务推送接口（用于接收服务端推送消息，messageType : 消息类型，message : 消息内容，详情查看类参考）
        @Override
        public void onTracePushCallback(byte messageType, final String message) {
            LogUtil.d(TAG, "start---onTracePushCallback-messageType=" + messageType + "---arg1=" + message);
//            FileUtils.writeFileFromString(fenceAlarmLog, message + "\n", true);

            AppEvent event = new AppEvent();
            event.setTag("SAVE_FENCE_ALARM_INFO");
            event.setMessage(message);
            EventBus.getDefault().post(event);

            showNotification(message);
        }

    };

    public static void closeTrace() {
        //停止轨迹服务
        if (client != null) {
            client.stopTrace(trace, stopTraceListener);
        }
        if (isRegister) {
            try {
                MyApplication.getContext().unregisterReceiver(trackReceiver);
                isRegister = false;
            } catch (Exception e) {
            }
        }
    }

    //实例化停止轨迹服务回调接口
    private static OnStopTraceListener stopTraceListener = new OnStopTraceListener() {
        // 轨迹服务停止成功
        @Override
        public void onStopTraceSuccess() {
            LogUtil.d(TAG, "stopTraceListener" + "---onStopTraceSuccess--" + "onStopTraceSuccess");
        }

        // 轨迹服务停止失败（errorNo : 错误编码，message : 消息内容，详情查看类参考 success）
        @Override
        public void onStopTraceFailed(int errorNo, String message) {
            LogUtil.d(TAG, "stopTraceListener" + "---onStopTraceFailed--" + "onStopTraceFailed---errorNo = " + errorNo +
                    "---message=" + message);
        }
    };

    private static void showNotification(String message) {
        TraceAlarmInfo info = GsonUtil.jsonToBean(message, TraceAlarmInfo.class);
        if (info != null) {
            NotificationManager manager = (NotificationManager) MyApplication.getContext().getSystemService(Context.NOTIFICATION_SERVICE);
            Notification.Builder builder = new Notification.Builder(MyApplication.getContext());
            builder.setContentTitle(info.getFence())
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
                    .setAutoCancel(true);
            if (info.getAction() == 1) {//进入围栏
                builder.setContentText("您已进入电子围栏");
            } else if (info.getAction() == 2) {//离开围栏
                builder.setContentText("您已离开电子围栏");
            }
            Notification notification = builder.build();
//            notification.flags = Notification.FLAG_INSISTENT;//不点击的话会一直震动
            manager.notify(1, notification);
        }
    }


    /**
     * 查询当前地理位置
     */
    public static void getCurrentLocation() {//final Handler handler
        client.queryRealtimeLoc(serviceId, new OnEntityListener() {
            //请求失败回调接口
            @Override
            public void onRequestFailedCallback(String message) {
                Log.d(TAG, "queryRealtimeLoc--onRequestFailedCallback--message=" + message);
            }

            //Entity实时定位回调接口
            @Override
            public void onReceiveLocation(TraceLocation traceLocation) {
                super.onReceiveLocation(traceLocation);
                AppEvent event = new AppEvent();
                event.setTag(Constant.GET_CURRENT_LOCATION);
                event.setObj1(traceLocation);
                EventBus.getDefault().post(event);

                LogUtil.dLocation(traceLocation);
            }
        });
    }

    public static void getCurrentLocation2(final LocateCallback callback) {
        try {
            client.queryRealtimeLoc(serviceId, new OnEntityListener() {
                //请求失败回调接口
                @Override
                public void onRequestFailedCallback(String message) {
                    Log.d(TAG, "queryRealtimeLoc--onRequestFailedCallback--message=" + message);
                }

                //Entity实时定位回调接口
                @Override
                public void onReceiveLocation(TraceLocation traceLocation) {
                    super.onReceiveLocation(traceLocation);
                    LogUtil.dLocation(traceLocation);

                    callback.exec(traceLocation);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //查询历史报警
    public static void queryFenceHistoryAlarmInfo(int fenceId, String monitoredPersons) {
        int beginTime = (int) (System.currentTimeMillis() / 1000 - 12 * 60 * 60);
        int endTime = (int) (System.currentTimeMillis() / 1000);
        client.queryFenceHistoryAlarmInfo(serviceId, fenceId, monitoredPersons, beginTime, endTime, new OnGeoFenceListener() {
            @Override
            public void onRequestFailedCallback(String s) {
                LogUtil.d(TAG, "onRequestFailedCallback=" + s);
            }

            @Override
            public void onQueryHistoryAlarmCallback(String s) {
                super.onQueryHistoryAlarmCallback(s);
                LogUtil.d(TAG, "onQueryHistoryAlarmCallback=" + s);
            }
        });
    }

    public static void createCircularFence() {

        String creator = entityName;// 创建者
        String fenceName = "围栏名称1"; // 围栏名称
        String fenceDesc = "围栏描述1";// 围栏描述
        String monitoredPersons = entityName; // 监控对象列表（多个entityName，以英文逗号"," 分割）
        String observers = entityName;// 观察者列表（多个entityName，以英文逗号"," 分割）
        String validTimes = "1600,1800";//生效时间列表 （一天中的几点几分到 几点几分生效。多个时间段使用分号”;”分隔。比如：“0820,0930;1030,1130”）
        int validCycle = 4;// 1：不重复2：工作日循环3：周末循环4：每天循环5：自定义
        String center = 121.490607 + "," + 31.338714;// 围栏圆心（圆心位置, 格式 : "经度,纬度"）
        int coordType = 3;// 坐标类型 （1：GPS经纬度，2：国测局经纬度，3：百度经纬度）
        double radius = 30;// 围栏半径（单位 : 米）
        //创建围栏
        client.createCircularFence(serviceId, creator, fenceName, fenceDesc, monitoredPersons, observers,
                validTimes, validCycle, null, null, coordType, center, radius, 0, 0, new OnGeoFenceListener() {
                    @Override
                    public void onRequestFailedCallback(String s) {
                        LogUtil.d(TAG, "创建围栏--onRequestFailedCallback--s=" + s);
                    }

                    @Override
                    public void onCreateCircularFenceCallback(String s) {
                        super.onCreateCircularFenceCallback(s);
                        LogUtil.d(TAG, "创建围栏--onCreateCircularFenceCallback--s=" + s);
                    }

                    @Override
                    public void onCreateLocalFenceCallback(CreateLocalFenceResult createLocalFenceResult) {
                        super.onCreateLocalFenceCallback(createLocalFenceResult);
                        LogUtil.d(TAG, "创建围栏--onCreateLocalFenceCallback");
                    }
                });
    }

    //查询监控者状态
    public static void queryMonitoredStatus(int fenceId) {
        String monitoredPersons = entityName;
        //查询实时状态
        client.queryMonitoredStatus(serviceId, fenceId, monitoredPersons, new OnGeoFenceListener() {
            //查询监控对象状态回调接口
            @Override
            public void onQueryMonitoredStatusCallback(String message) {
                super.onQueryMonitoredStatusCallback(message);
//                FileUtils.writeFileFromString(fenceAlarmLog, "\n查询监控对象状态回调接口:" + message + ",时间：" + TimeUtils.millis2String(System
//                        .currentTimeMillis()), true);
                LogUtil.d(TAG, "status-message" + message);

            }

            @Override
            public void onRequestFailedCallback(String message) {
//                FileUtils.writeFileFromString(fenceAlarmLog, "\nOnGeoFenceListener:===onRequestFailedCallback==" + message + ",时间：" + TimeUtils.millis2String(System
//                        .currentTimeMillis()), true);
                LogUtil.d(TAG, "falil_message" + message);
            }
        });
    }

    //    根据坐标查询监控者状态
    public static void queryMonitoredStatusByLocation(int fenceId, TraceLocation traceLocation) {
        String locations = String.valueOf(traceLocation.getLongitude()) + "," + String.valueOf(traceLocation.getLatitude()) + ",3";
        LogUtil.d(TAG, "locations=" + locations);
        String monitoredPersons = entityName;
        client.queryMonitoredStatusByLocation(serviceId, fenceId, monitoredPersons, locations, new OnGeoFenceListener() {

            @Override
            public void onQueryMonitoredStatusCallback(String message) {
                super.onQueryMonitoredStatusCallback(message);
                LogUtil.d(TAG, "message=" + message);
                MonitorStatusBean monitorStatusBean = GsonUtil.jsonToBean(message, MonitorStatusBean.class);
                AppEvent event = new AppEvent();
                for (int i = 0; i < monitorStatusBean.getMonitored_person_statuses().size(); i++) {
                    MonitoredPersonStatusesBean info = monitorStatusBean.getMonitored_person_statuses().get(i);
                    if (entityName.equals(info.getMonitored_person())) {//包含这个司机
                        if (info.getMonitored_status() == 1) {//在围栏内
                            event.setTag(Constant.IN_FENCE);
                            LogUtil.d(TAG, "在围栏内");
                        } else {//围栏外
                            event.setTag(Constant.OUT_FENCE);
                            LogUtil.d(TAG, "在围栏外");
                        }
                        EventBus.getDefault().post(event);
                        return;
                    }
                }
            }

            @Override
            public void onRequestFailedCallback(String message) {
                LogUtil.d(TAG, "fail_message=" + message);
            }
        });
    }

    /**
     * 查询历史轨迹
     */
    public static void queryHistoryTrack() {
        // 是否返回精简结果
        int simpleReturn = 0;
        // 是否纠偏
        int isProcessed = 0;
        // 纠偏选项
        String processOption = null;
        // 开始时间
        int startTime = 1499328033;//
        // 结束时间
        int endTime = 1499331633;//
        // 分页大小
        int pageSize = 5000;
        // 分页索引
        int pageIndex = 1;
        client.queryHistoryTrack(serviceId, entityName, simpleReturn, isProcessed, processOption, startTime, endTime, pageSize, pageIndex,
                new OnTrackListener() {
                    @Override
                    public void onRequestFailedCallback(String message) {
                        LogUtil.d(TAG, "查询轨迹失败message=" + message);
                        FileUtils.writeFileFromString(historyTrackLog, message + "时间：" + TimeUtils.millis2String(System.currentTimeMillis()) + "\n", true);
                    }

                    @Override
                    public void onQueryHistoryTrackCallback(String message) {
                        super.onQueryHistoryTrackCallback(message);
                        LogUtil.d(TAG, "查询历史轨迹成功message=" + message);
                        FileUtils.writeFileFromString(historyTrackLog, message + "时间：" + TimeUtils.millis2String(System.currentTimeMillis()) + "\n", true);
                    }
                });
    }

    private static File fenceAlarmLog;
    private static File historyTrackLog;
    private static boolean flagFenceAlarm;
    private static boolean flagHistoryTrack;

    //创建警报和历史轨迹 文件
    private static void createLogFile() {
        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/baiWeiLogFenceAlarm.txt";
        String path2 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/baiWeiLogHistoryTrack.txt";
        Log.d(TAG, "PATH=" + path);
        fenceAlarmLog = new File(path);
        historyTrackLog = new File(path2);
        flagFenceAlarm = FileUtils.createOrExistsFile(fenceAlarmLog);
        flagHistoryTrack = FileUtils.createOrExistsFile(historyTrackLog);
    }
}
